<template>
  <v-stage :config="props">
    <v-layer>
      <template v-for="[key, value] in drawingGraphs" :key="key">
        <v-group v-for="graph in value" v-if="value?.length" :key="graph?.vueComponentName"
          :config="graph?.konvaGraphConfig">
          <KonvaGraphNode v-for="child in graph.graphsConfigItems" v-if="graph?.graphsConfigItems?.length"
            :key="child.vueComponentName" :node="child" />
        </v-group>
      </template>
      <template v-for="graph in konvaConfigRois">
        <component :is="graph.vueComponentName" :config="graph.konvaGraphConfig" />
      </template>
    </v-layer>
  </v-stage>
</template>

<script setup lang="ts">
defineOptions({
  name: "TargetHighlightLayer",
  inheritAttrs: false,
});

import { useMqtt } from "@/hooks/useMqtt";
import {
  updateKonvaConfigBasedOnLatestSize,
  getKonvaListOfSkeletonGroup,
  getRoiLineConfig,
} from "@/utils/data-transformers";
import {
  CAMERA_STREAM_NULL,
  CAMERA_STREAM_ID,
  ANOMALY_DETECTION_TYPE,
} from "@/utils/constants";
import { isRectIntersectPolygon } from "@/utils";
import { xmeDSIC_Solutions_GetRoiCameraBind } from "@/data-services/api/index";
import IdleChecker from "@/utils/idle-checker";
import type { T_GraphsConfigItem2 } from "@/types/graphs-konva.ts";
import type { MmC3d_InferenceResult } from "@/types/raw-data";
const props = defineProps({
  width: {
    type: Number,
    default: 0,
  },
  height: {
    type: Number,
    default: 0,
  },
  cameraId: {
    type: String,
    default: "",
  },
  currentTargetHighlightLayer: {
    type: String,
    default: "",
  },
  currentPipelineId: {
    type: String,
    default: "",
  },
});

const { subscribe, unsubscribe } = useMqtt();

const drawingGraphsMap = ref<Map<string, KonvaGroupConfig[]>>(new Map());
const drawingGraphs = computed(() => {
  return Array.from(drawingGraphsMap.value.entries());
});
const konvaConfigRoisMap = ref<Map<string, [] | T_GraphsConfigItem2[]>>(
  new Map()
);
const konvaConfigRois = computed(() => {
  if (!props.currentPipelineId) {
    return [];
  }
  const config = konvaConfigRoisMap.value.get(props.currentPipelineId);
  return config;
});

const idleChecker = new IdleChecker({ idleThreshold: 500 });

idleChecker.setIdleCallback(() => {
  drawingGraphsMap.value.clear();
});

const lastProcessedTime = ref<number>(0);
const FPS_30_INTERVAL = 80; // 每帧间隔时间（毫秒）
// const worker = new Worker(new URL("@/worker/mqtt-worker.ts", import.meta.url), {
// 	type: "module",
// });

// 检查并更新检测框颜色（根据是否与ROI相交）
const updateDetectionBoxColors = (
  konvaList: KonvaGroupConfig[],
  roiConfig: T_GraphsConfigItem2[]
) => {
  if (!roiConfig?.length) return;

  konvaList.forEach((detectionGroup) => {
    const bbox = detectionGroup.konvaGraphConfig;
    
    // 检查该检测框是否与任意ROI相交
    let hasIntersection = false;
    
    for (const roiItem of roiConfig) {
      if (roiItem.konvaGraphConfig?.points) {
        const isIntersecting = isRectIntersectPolygon(
          {
            x: bbox.x,
            y: bbox.y,
            width: bbox.width,
            height: bbox.height,
          },
          roiItem.konvaGraphConfig.points
        );
        
        if (isIntersecting) {
          hasIntersection = true;
          break; // 只要找到一个相交就够了
        }
      }
    }
    
    // 根据是否相交，修改检测框的颜色
    // 绿色：相交，红色：正常
    const targetColor = hasIntersection ? "rgb(0, 255, 0)" : "rgb(255, 0, 0)";
    
    // 找到检测框的矩形配置并修改颜色
    detectionGroup.graphsConfigItems?.forEach((child) => {
      if (child.vueComponentName === "v-rect") {
        child.konvaGraphConfig.stroke = targetColor;
      }
      // 同时修改标签背景色
      if (child.vueComponentName === "v-label") {
        child.graphsConfigItems?.forEach((child2) => {
          if (child2.vueComponentName === "v-tag") {
            child2.konvaGraphConfig.fill = targetColor;
          }
        });
      }
    });
  });
};

// 处理 目标检测 结果
const handleDetectionResult = (topic: string, data: Record<string, any>) => {
  data?.batched_results?.forEach((result: MmC3d_InferenceResult) => {
    if (result.camera_id === props.cameraId) {
      if (result.results?.length) {
        // 收到消息时更新时间戳，并重置触发状态
        idleChecker.updateLastMessageTime();
        const unConvert = topic === ANOMALY_DETECTION_TYPE;
        const { konvaList } = getKonvaListOfSkeletonGroup(
          result,
          "target",
          unConvert
        );

        updateKonvaConfigBasedOnLatestSize(
          konvaList,
          props.width,
          props.height
        );

        // 检查碰撞并更新颜色
        const roiConfig = konvaConfigRoisMap.value.get(props.currentPipelineId);
        if (roiConfig && Array.isArray(roiConfig) && roiConfig.length) {
          updateDetectionBoxColors(konvaList, roiConfig as T_GraphsConfigItem2[]);
        }

        drawingGraphsMap.value.set(result.pipeline_id, konvaList);
      }
    }
  });
};
const callbackHandler = (topic: string, message: string) => {
  const now = Date.now();
  if (now - lastProcessedTime.value < FPS_30_INTERVAL) {
    return; // 未达到30帧间隔，跳过处理
  }

  window.requestAnimationFrame(() => {
    lastProcessedTime.value = now; // 更新最后处理时间

    if (idleChecker.rafId === 0) {
      idleChecker.start(); // 启动空闲检测
    }
    const data = JSON.parse(message);

    switch (topic) {
      case CAMERA_STREAM_ID: {
        handleDetectionResult(topic, data);
        break;
      }
      default:
        break;
    }

    // const encoder = new TextEncoder();
    // const arrayBuffer = encoder.encode(message).buffer;
    // try {
    // 	// console.log(topic, "message", arrayBuffer, props.width, props.height, props.cameraId);
    // 	worker.postMessage(
    // 	{
    // 		topic,
    // 		message: arrayBuffer,
    // 		width: props.width,
    // 		height: props.height,
    // 		cameraId: props.cameraId,
    // 		// idleChecker,
    // 	},
    // 	[arrayBuffer]
    // );
    // } catch (error) {
    // 	console.error("Error terminating worker:", error);
    // }
  });
};
const updataRoiSize = (roiConfig: T_GraphsConfigItem2[]) => {
  if (roiConfig?.length) {
    roiConfig.forEach((item) => {
      const realConfigItem = item.konvaGraphConfig.points?.map(
        (val: number, i: number) => {
          return i % 2 === 0
            ? Math.ceil(val * props.width)
            : Math.ceil(val * props.height);
        }
      );
      item.konvaGraphConfig.points = realConfigItem;
    });
  }
};
// 原始数据
const restoreRoiConfig = ref<T_GraphsConfigItem2[]>([]);
async function getRoiConfig() {
  if (!props.cameraId || !props.currentPipelineId) return;
  try {
    const roiConfig = await xmeDSIC_Solutions_GetRoiCameraBind({
      cameraId: props.cameraId,
      pipelineId: props.currentPipelineId,
    });
    const {
      data: { configList: roiList },
    } = roiConfig;
    if (roiList?.length) {
      restoreRoiConfig.value = getRoiLineConfig(roiList[0].rois ?? []);
    } else {
      konvaConfigRoisMap.value.delete(props.currentPipelineId);
      // ElMessage.warning("当前方案无ROI配置");
    }
  } catch (error) {
    // ElMessage.error("获取ROI配置失败");
  }
}


watch(
  () => props.currentTargetHighlightLayer,
  (value: string, _, onCleanup) => {
    if (value === CAMERA_STREAM_NULL) return;
    const isValidTopic = [CAMERA_STREAM_ID].includes(value);

    if (isValidTopic) {
      subscribe(value, callbackHandler);
    }

    onCleanup(() => {
      // 取消旧订阅并清空数据
      unsubscribe(value, callbackHandler);
      drawingGraphsMap.value.clear();
    });
  }
);

watch([() => props.width, () => props.height], ([width, height]) => {
  drawingGraphsMap.value?.forEach((value) => {
    // 更新检测结果数据
    updateKonvaConfigBasedOnLatestSize(value, width, height);
    
    // 重新检查碰撞并更新颜色
    const roiConfig = konvaConfigRoisMap.value.get(props.currentPipelineId);
    if (roiConfig && Array.isArray(roiConfig) && roiConfig.length) {
      updateDetectionBoxColors(value, roiConfig as T_GraphsConfigItem2[]);
    }
  });
  if (restoreRoiConfig.value) {
    const copylist = JSON.parse(JSON.stringify(restoreRoiConfig.value));
    updataRoiSize(copylist);
    konvaConfigRoisMap.value.set(props.currentPipelineId, copylist);
  }
});
watch(
  () => props.currentPipelineId,
  (value: string) => {
    if (value) {
      getRoiConfig();
    } else {
      konvaConfigRoisMap.value.clear();
    }
  },
  { immediate: true }
);
watch(
  () => props.cameraId,
  () => {
    // 重置数据
    drawingGraphsMap.value.clear();
    konvaConfigRoisMap.value.clear();
  }
);

onBeforeUnmount(() => {
  // 取消旧订阅并清空数据
  unsubscribe(CAMERA_STREAM_ID);
  drawingGraphsMap.value.clear();
  // 销毁检测器
  idleChecker.destroy();
});
onMounted(() => {
  // worker.onmessage = (event) => {
  // 	const { topic, result, cameraId, error } = event.data;
  // 	if (error) {
  // 		console.error("Worker error:", error);
  // 		return;
  // 	}
  // 	if (result) {
  // 		//  && props.cameraId === cameraId
  // 		drawingGraphsMap.value.set(topic, result);
  // 		// console.log("7777777Worker result:", drawingGraphsMap.value);
  // 	}
  // };
});
</script>
